package com.aispeech.asr.apis.detection.websocket.emitter;

import java.io.IOException;
import java.util.List;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.web.reactive.socket.WebSocketSession;

import com.aispeech.asr.apis.detection.config.AppConfig;
import com.aispeech.asr.apis.detection.vo.SedVo;
import com.aispeech.asr.apis.detection.websocket.connection.DateBufferFactory;
import com.aispeech.asr.apis.detection.websocket.connection.EmitterManager;
import com.aispeech.jarpc.ArpcException;
import com.aispeech.jarpc.JArpc;
import com.aispeech.jarpc.message.ArpcMessage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

@ToString
@Slf4j
public class ClientEmitter extends Emitter {
	
	private String audioPath;
    private String requestQuery;
    private JSONObject startObj;
    private JSONObject audioObj;
    private AppConfig appConfig;
    private String sessionId;
    private JArpc jarpc;
    //private SedOnlineCallback sedOnlineCallback;
    
    private int receiveTimes;
    private DataBuffer receiveBuffer; 
    
    private boolean running = false; 
    
    public synchronized void writeReceiveBuffer(DataBuffer dataBuffer){
		if(receiveBuffer == null) {
			receiveBuffer = DateBufferFactory.getInstance().allocateBuffer();
		}
		receiveBuffer.write(dataBuffer);
    }

    public ClientEmitter(WebSocketSession session, String id, EmitterManager manager) {
        super(session, id, EmitterType.CLIENT, manager);
 
        running = true;
        //new Thread(this::integrationLoop).start();
    }
    
    
    public void setAudioPath(String audioPath) {
        this.audioPath = audioPath;
    }
    
    public String getAudioPath() {
        return audioPath;
    }
    
    public void setRequestQuery(String requestQuery) {
        this.requestQuery = requestQuery;
    }
    
    public String getRequestQuery() {
        return requestQuery;
    }
    
    public void setStartObj(JSONObject startObj) {
        this.startObj = startObj;
    }
    
    public JSONObject getStartObj() {
        return startObj;
    }
    
    public void setAudioObj(JSONObject audioObj) {
        this.audioObj = audioObj;
    }
    
    public JSONObject getAudioObj() {
        return audioObj;
    }
    
    public void setAppConfig(AppConfig appConfig) {
        this.appConfig = appConfig;
    }
    
    public AppConfig getAppConfig() {
        return appConfig;
    }
    
//    public void setSedOnlineCallback(SedOnlineCallback sedOnlineCallback) {
//        this.sedOnlineCallback = sedOnlineCallback;
//    }
//    
//    public SedOnlineCallback getSedOnlineCallback() {
//        return sedOnlineCallback;
//    }
    
    public void setJarpc(JArpc jarpc) {
        this.jarpc = jarpc;
    }
    
    public JArpc getJarpc() {
        return jarpc;
    }
    
    public void setSessionId(String sesssionId) {
        this.sessionId = sesssionId;
    }
    
    public String getSessionId() {
        return sessionId;
    }
    
    public void setRunning(boolean flag) {
        this.running = flag;
    }
   
    public void addReceiveTimes() {
         receiveTimes++;
    }
    
    public int getReceiveTimes() {
        return receiveTimes;
    }
    
    public DataBuffer getReceiveBuffer() {
    	return this.receiveBuffer;
    }
    
    public void doSed(DataBuffer dataBuffer) {
    	try {
    		
    		if(dataBuffer.readableByteCount() > 0) {
    			jarpc.feed(dataBuffer.asByteBuffer().array(), dataBuffer.readableByteCount());
    		}else {
    			ArpcMessage message = jarpc.stop(3);
    			List<SedVo> resultList = JSONArray.parseArray(new String(message.getBody(), "utf-8"), SedVo.class);
    			getManager().doResponse(getId(), resultList, 1);
    		}
		} catch (IOException e) {
			log.error("[ClientEmitter IOException] do sed failed.sessionId:{}",getId(),e);
			getManager().doErrorResponse(getId(), e);
		} catch (ArpcException e) {
			log.error("[ClientEmitter ArpcException] do sed failed.sessionId:{}",getId(),e);
			getManager().doErrorResponse(getId(), e);
		}
    }
    
}
